package edu.rpi.tw.pml.browsing.server;

import java.util.ArrayList;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class TDBConnector {

	/*
	 * Server-side helper class to carry out SPARQL queries. This class is
	 * greatly in need of refactoring.
	 */

	private final String serviceURL = "http://tw2.tw.rpi.edu:2020/sparql?query=";
	// private final String serviceURL =
	// "http://plato.cs.rpi.edu:8080/joseki/sparql/tdb-iwsearch?query=";
	private final String resultFormat = "&output=json";

	public TDBConnector() {
	}

	public TDBConnector(String dir) {
	}

	/*
	 * Get values for a given facet name
	 */
	public String getValuesByFacetName(String facetName) {

		String resultString = "";
		String queryString = "";
		try {
			queryString = URLEncoder.encode("SELECT DISTINCT ?o WHERE { ?s <"
					+ facetName + "> ?o. } limit 50", "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			System.out.println("Error while encoding url.");
		}

		String httpRequestURL = serviceURL + queryString + resultFormat;

		try {
			URL url = new URL(httpRequestURL);
			HttpURLConnection myConnection = (HttpURLConnection) url
					.openConnection();
			myConnection.connect();

			// System.out.println("Response Message: "
			// + myConnection.getResponseMessage());

			InputStream in = myConnection.getInputStream();
			BufferedInputStream bin = new BufferedInputStream(in);
			for (;;) {
				int data = bin.read();
				if (data == -1) {
					break;
				} else {
					resultString += (char) data;
				}
			}
		} catch (Exception e) {
			System.out.println("Error while retrieving SPARQL results.");
		}

		return resultString;
	}

	/*
	 * Method to get all facets from SPARQL endpoint.
	 */
	public String getAllFacets() {
		String resultString = "";
		String queryString = "";
		try {
			queryString = URLEncoder.encode(
					"SELECT DISTINCT ?p WHERE { ?s ?p ?o. }", "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			System.out.println("Error while encoding url.");
		}

		String httpRequestURL = serviceURL + queryString + resultFormat;

		try {
			URL url = new URL(httpRequestURL);
			HttpURLConnection myConnection = (HttpURLConnection) url
					.openConnection();
			myConnection.connect();

			// System.out.println("Response Message: "
			// + myConnection.getResponseMessage());

			InputStream in = myConnection.getInputStream();
			BufferedInputStream bin = new BufferedInputStream(in);
			for (;;) {
				int data = bin.read();
				if (data == -1) {
					break;
				} else {
					resultString += (char) data;
				}
			}
		} catch (Exception e) {
			System.out.println("Error while retrieving SPARQL results.");
		}

		return resultString;
	}

	/*
	 * Method to get all classes/concepts from SPARQL endpoint.
	 */
	public String getAllConcepts() { // TODO need refactoring.
		String resultString = "";

		String queryString = "";
		try {
			queryString = URLEncoder.encode(
					"select distinct ?concept where {?s a ?concept.}", "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			System.out.println("Error while encoding url.");
		}

		String httpRequestURL = serviceURL + queryString + resultFormat;

		try {
			URL url = new URL(httpRequestURL);
			HttpURLConnection myConnection = (HttpURLConnection) url
					.openConnection();
			myConnection.connect();

			// System.out.println("Response Message: "
			// + myConnection.getResponseMessage());

			InputStream in = myConnection.getInputStream();
			BufferedInputStream bin = new BufferedInputStream(in);
			for (;;) {
				int data = bin.read();
				if (data == -1) {
					break;
				} else {
					resultString += (char) data;
				}
			}
			// System.out.println(resultString);
		} catch (Exception e) {
			System.out.println("Error while retrieving SPARQL results.");
		}
		return resultString;
	}

	/*
	 * Get all instances from SPARQL endpoint.
	 */
	public String getAllInstances() { // TODO need refactoring.
		String resultString = "";

		String queryString = "";
		try {
			queryString = URLEncoder
					.encode(
							"select distinct ?i ?p ?o where {?i a ?c. ?i ?p ?o.} limit 50",
							"UTF-8");
		} catch (UnsupportedEncodingException e1) {
			System.out.println("Error while encoding url.");
		}
		String httpRequestURL = serviceURL + queryString + resultFormat;

		try {
			URL url = new URL(httpRequestURL);
			HttpURLConnection myConnection = (HttpURLConnection) url
					.openConnection();
			myConnection.connect();

			// System.out.println("Response Message: "
			// + myConnection.getResponseMessage());

			InputStream in = myConnection.getInputStream();
			BufferedInputStream bin = new BufferedInputStream(in);
			for (;;) {
				int data = bin.read();
				if (data == -1) {
					break;
				} else {
					resultString += (char) data;
				}
			}
			// System.out.println(resultString);
		} catch (Exception e) {
			System.out.println("Error while retrieving SPARQL results.");
		}
		return resultString;
	}

	/*
	 * Get instances according to user selected facet values.
	 */
	public String getInstances(ArrayList<String> conceptList) {
		String resultString = "";
		String queryString = "";
		String SELECT_BEGIN = "select distinct ?i ?p ?o where { ";
		String SELECT_END = " } limit 50";
		String UNION = " UNION ";
		String portions = "";

		for (int i = 0; i < conceptList.size(); i++) {
			if (i == conceptList.size() - 1) {
				portions += "{?i a <" + conceptList.get(i) + ">. ?i ?p ?o.}";
			} else {
				portions += "{?i a <" + conceptList.get(i) + ">. ?i ?p ?o.}"
						+ UNION;
			}
		}

		queryString = SELECT_BEGIN + portions + SELECT_END;

		try {
			queryString = URLEncoder.encode(queryString, "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			System.out.println("Error while encoding url.");
		}
		String httpRequestURL = serviceURL + queryString + resultFormat;

		try {
			URL url = new URL(httpRequestURL);
			HttpURLConnection myConnection = (HttpURLConnection) url
					.openConnection();
			myConnection.connect();

			// System.out.println("Response Message: "
			// + myConnection.getResponseMessage());

			InputStream in = myConnection.getInputStream();
			BufferedInputStream bin = new BufferedInputStream(in);
			for (;;) {
				int data = bin.read();
				if (data == -1) {
					break;
				} else {
					resultString += (char) data;
				}
			}
			// System.out.println(resultString);
		} catch (Exception e) {
			System.out.println("Error while retrieving SPARQL results.");
		}
		return resultString;
	}
}